package com.gxar.quick.ar.server.base.facade;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.gxar.common.entity.Result;
import com.gxar.common.exception.APIRuntimeException;
import com.gxar.common.utils.JacksonUtils;
import com.gxar.common.utils.StringSpliceUtils;
import com.gxar.common.utils.StringUtils;
import com.gxar.quick.ar.server.base.common.constant.WechatPayConstant;
import com.gxar.quick.ar.server.base.model.ResultCodeEnum;
import com.gxar.quick.ar.server.base.model.share.info.AccessTokenInfo;
import com.gxar.quick.ar.server.base.model.share.vo.request.UnlimitedQRCodeRequest;
import com.gxar.quick.ar.server.base.model.share.vo.response.UnlimitedQRCodeResponse;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author nice
 * @version 1.0
 * @created 2023/11/25.
 */
@Service
@Slf4j
public class ShareFacade {

    public UnlimitedQRCodeResponse getUnlimitedQRCode(UnlimitedQRCodeRequest param) {
        //获取token
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}";
        url = StringSpliceUtils.splice(url, WechatPayConstant.APP_ID, WechatPayConstant.APP_SECRET);
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("scene", param.getWorksId());
        requestMap.put("page", param.getPage());
        if (StringUtils.isNotBlank(param.getEnv())) {
            requestMap.put("env_version", param.getEnv());
        }
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(url).build();
        try (Response response = client.newCall(request).execute()) {
            UnlimitedQRCodeResponse result = new UnlimitedQRCodeResponse();
            AccessTokenInfo accessTokenInfo = JacksonUtils.parseObject(response.body().string(), AccessTokenInfo.class);
            String accessToken = accessTokenInfo.getAccess_token();
            if (StringUtils.isBlank(accessToken)) {
                return result;
            }
            String getUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={}";
            getUrl = StringSpliceUtils.splice(getUrl, accessToken);
            byte[] wechatQrcodeBytes = getWechatQrcodeByOkhttp3(getUrl, requestMap);
            BASE64Encoder encoder = new BASE64Encoder();
            String data = encoder.encode(wechatQrcodeBytes);
            result.setBuffer(data);
            return result;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public byte[] getWechatQrcodeByOkhttp3(String url, Map<String, Object> body) {
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        okhttp3.MediaType mediaType = okhttp3.MediaType.parse("application/json");
        RequestBody requestBody = RequestBody.create(mediaType, JSONObject.toJSONString(body));
        Request request = new Request.Builder().url(url).method("POST", requestBody).build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                if (!StringUtils.equals("image", response.body().contentType().type())) {
                    log.warn("share failed : {}", response.body().string());
                    throw new APIRuntimeException(ResultCodeEnum.SHARE_FAILED);
                }
                return response.body().bytes();
            }
        } catch (IOException e) {
            log.warn("getWechatQrcode error", e);
        }
        return null;
    }

    public void getUnlimitedQRCode(HttpServletResponse httpServletResponse, String scene, String page) {
        //获取token
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}";
        url = StringSpliceUtils.splice(url, WechatPayConstant.APP_ID, WechatPayConstant.APP_SECRET);
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("scene", scene);
        requestMap.put("page", page);
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(url).build();
        try (Response response = client.newCall(request).execute()) {
            AccessTokenInfo accessTokenInfo = JacksonUtils.parseObject(response.body().string(), AccessTokenInfo.class);
            String accessToken = accessTokenInfo.getAccess_token();
            if (StringUtils.isBlank(accessToken)) {
                httpServletResponse.setContentType("application/json;charset=UTF-8");
                PrintWriter writer1 = httpServletResponse.getWriter();
                writer1.write(JSON.toJSONString(Result.error(ResultCodeEnum.SHARE_FAILED)));
                writer1.flush();
                writer1.close();
                return;
            }
            String getUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={}";
            getUrl = StringSpliceUtils.splice(getUrl, accessToken);
            ServletOutputStream data = null;
            try (InputStream inputStream = getWechatQrcodeByOkhttp3ToInput(getUrl, requestMap)){
                data = httpServletResponse.getOutputStream();
                // 5M一次读写
                byte[] buffer = new byte[1024 * 1024 * 5];
                int len;
                while ((len = inputStream.read(buffer)) != -1) {
                    data.write(buffer, 0, len);
                }
            } finally {
                if (null != data) {
                    try {
                        data.close();
                    } catch (IOException e) {
                        log.debug("获取分享码流关闭异常");
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public InputStream getWechatQrcodeByOkhttp3ToInput(String url, Map<String, Object> body) {
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        okhttp3.MediaType mediaType = okhttp3.MediaType.parse("application/json");
        RequestBody requestBody = RequestBody.create(mediaType, JSONObject.toJSONString(body));
        Request request = new Request.Builder().url(url).method("POST", requestBody).build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                if (!StringUtils.equals("image", response.body().contentType().type())) {
                    log.warn("share failed : {}", response.body().string());
                    throw new APIRuntimeException(ResultCodeEnum.SHARE_FAILED);
                }
                return response.body().byteStream();
            }
        } catch (IOException e) {
            log.warn("getWechatQrcode error", e);
        }
        return null;
    }
}
